﻿using DotNetExtensions.Core.Autofac;
using DotNetExtensions.Core;
using DotNetExtensions.Core.Converters;
using DotNetExtensions.Core.Encryptions;
using Habi.Server.Models;
using Habi.Server.Repositorys;
using Habi.Server.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DotNetExtensions.Core.IOC;
using System.Text;

namespace Habi.Server.Services
{
    [AutoInject]
    public interface IUserService
    {
        LoginViewModel Regist(RegistUserModel regist);
        LoginViewModel Login(LoginViewModel data);
    }
    public class UserService : IUserService
    {
        private SolverDbContext context;
        public UserService(SolverDbContext context)
        {
            this.context = context;
        }

        private string KeyFromMac(string mac)
        {
            return string.Format("{0}habi", mac.Replace(":", "").ToLower());
        }
        public LoginViewModel Regist(RegistUserModel regist)
        {
            bool exists = context.Users.Exists(c => c.PhoneNumber == regist.PhoneNumber);
            if (exists) throw new Exception($"This phone number is already registered");

            LoginViewModel data = new LoginViewModel();
            UserModel user = new UserModel()
            {
                Name = regist.Name,
                PhoneNumber = regist.PhoneNumber,
                Id = Snowflake.Default.NextShortId(),
                CreateTime = DateTime.Now,
                Creator = "system",
                Host = regist.Host,
                Mac = regist.Mac
            };


            bool result = context.Users.Insert(user);

            if (result)
            {
                data.Mac = regist.Mac;
                data.Name = regist.Name;
                data.Id = user.Id;
                data.Token = new AES(Encoding.UTF8, KeyFromMac(data.Mac)).Encrypt($"{data.Mac}|{DateTimeConvert.GetTimestamp(DateTime.Now.AddDays(30))}");
            }

            return data;
        }

        public LoginViewModel Login(LoginViewModel data)
        {
            if (string.IsNullOrEmpty(data.Mac) || string.IsNullOrEmpty(data.Token)) throw new Exception("Invalid login data.");

            string token = new AES(Encoding.UTF8, data.Mac).Decrypt(data.Token);
            // mac | tick
            string tick = token.Split('|')[1];

            if (DateTime.Now > DateTimeConvert.Parse(Convert.ToInt64(tick)))
            {
                data.Timeout = true;
            }
            else
            {
                var registUsers = context.Users.Get(c => c.Mac == data.Mac);
                if (registUsers.Any())
                {
                    var user = registUsers.First();
                    data.Name = user.Name;
                    data.Id = user.Id;
                    data.Token = new AES(Encoding.UTF8, KeyFromMac(data.Mac)).Encrypt($"{data.Mac}|{DateTimeConvert.GetTimestamp(DateTime.Now.AddDays(30))}");
                }
            }
            return data;
        }
    }
}
